/*
 * Copyright (C) 2009-2011 Knowings
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 3
 * as published by the Free Software Foundation.
 *

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package com.knowings.tbs;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import com.knowings.tbs.operation.UnsupportedLanguageException;
import com.knowings.tbs.permission.PermissionException;
import com.knowings.tbs.query.QueryRuntimeException;
import com.knowings.tbs.trace.*;

/**
 * Interface describing Trace Repository compliance level 1 features.
 * 
 * @author privarola
 */
public interface ILevel1Features {

  /**
   * Method retrieving a list of description containers for the accessible stored traces.
   * @return a List object containing the descriptions.
   */
  public List<ITraceDescriptor> getTracesDescriptors();

  /**
   * Method retrieving a trace regarding a given uid.
   * @param uid a String object representing the given uid. This shouldn't be null.
   * @return an ITrace object which uid is equal to the given argument.
   * @throws NoSuchObjectException if the uid does not match any known trace in the current workspace
   * @throws PermissionException if the connected user does not have read privileges on the matching trace
   */
  public ITrace getTrace(String uid) throws PermissionException, NoSuchObjectException;

  /**
   * Method retrieving a list of traces identified by their uids.
   * @param uids a String array object containing the requested uids
   * @return a list of ITrace object which uid is equal to the given argument.
   * @throws NoSuchObjectException if one of the requested uids does not match any known trace in the current workspace
   * @throws PermissionException if the connected user does not have read privileges on the matching trace
   */
  public List<ITrace> getTraces(String[] uids) throws PermissionException, NoSuchObjectException;

  /**
   * Method adding a given trace to the Trace Repository.
   * All related obsels and relations will also be created in the trace repository.
   * If specified the given trace UID will be ignored and a new one will be generated.
   * @param trace a ITrace object representing the trace to add.
   * @return the UID of the newly added trace
   * @throws PermissionException if the connected user does not have the right to add a trace
   * @throws TraceIntegrityException if the given trace is not valid or incomplete
   */
  public String addTrace(ITrace trace) throws PermissionException, TraceIntegrityException;

  /**
   * Method updating an existing trace in the Trace Repository.
   * Some related objects like relations, obsels or attributes may be removed if they are not referenced any more. 
   * Some new obsels and relations may be created in the trace repository,
   * but no other <code>ITrace</code> or <code>IOperation</code> instance.
   * Such a modification will be considered as a trace amendment, thus breaking the trace monotony.
   * @param trace a ITrace object representing the trace to update; it must have a known UID.
   * @throws NoSuchObjectException if the trace UID or a referenced transformation is not found in the repository
   * @throws PermissionException if the connected user does not have the right to modify this trace
   */
  public void updateTrace(ITrace trace) throws NoSuchObjectException, PermissionException;

  /**
   * Method deleting an existing trace from the Trace Repository.
   * All related objects like relations, obsels or attributes will be removed.
   * Deleting a trace involved in a transformation execution puts in obsolete state all resulting traces.
   * @param uid the UID of an existing trace
   * @throws NoSuchObjectException if the trace UID is not found in the repository
   * @throws PermissionException if the connected user does not have the right to delete this trace
   */
  public void deleteTrace(String uid) throws NoSuchObjectException, PermissionException;

  /**
   * Method adding an obsel to an existing trace identified by its UID.
   * If the obsel end date is not greater than or equal to the last trace obsel end date, 
   * the operation breaks the trace monotony.
   * @param trace_uid the UID of the trace to be enriched
   * @param obsel the Observed Element description
   * @return the UID of the created obsel
   * @throws NoSuchObjectException if the trace UID is not found in the repository
   * @throws PermissionException if the connected user does not have the right to add an obsel to the target trace
   */
  public String addObsel(String trace_uid, IObselStructure obsel) throws NoSuchObjectException, PermissionException;

  /**
   * Method adding a relation to a Trace in the current workspace.
   * The relation "from" and "to" extremities identified by their UID should already exist in the same trace.
   * If specified the given relation UID will be ignored and a new one will be generated.
   * Adding a relation this way will be considered as a trace amendment. It the monotony is a concern,
   * the relation should be added in the same bulk as its extremities using the addTraceElements method.
   * @param relation a IRelation object representing a relation between two obsels
   * @param trace_uid the UID of the trace to be enriched
   * @return the UID of the newly added relation
   * @throws PermissionException if the connected user does not have the right to add a relation
   * @throws NoSuchObjectException if any of the referenced extremities does not exist in the workspace
   * @throws TraceIntegrityException if the referenced extremities do not belong to the same Trace
   */
  public String addRelation(String trace_uid, IRelationStructure relation) throws PermissionException,
      NoSuchObjectException, TraceIntegrityException;

  /**
   * This method is a bulk operation allowing adding several obsels and relations at a time.
   * It also allows updating the trace in a monotonous way if all added elements are positioned
   * after the last obsel present in the trace.
   * A call to this method will be considered monotonous if the new obsels come after the last trace obsel 
   * (considering the end dates) and all new relations only invole new obsels.
   * @param trace_uid the uid of the trace to be updated
   * @param obsels the obsels to be added
   * @param relations the relations to be added
   * @throws PermissionException if the connected user does not have the right to add a relation
   * @throws NoSuchObjectException if any of the referenced extremities does not exist in the workspace
   * @throws TraceIntegrityException if a relation referenced extremities do not belong to the same Trace
   */
  public void addTraceElements(String trace_uid, IObselStructure[] obsels, IRelationStructure[] relations)
      throws PermissionException, NoSuchObjectException, TraceIntegrityException;

  /**
   * Method retrieving a list of object as the results of a query executed on the fusion of several traces
   * @param trace_uids the uids of the traces to be taken into account (and merged) as data source for the query
   * @param query the query defined as a string
   * @param language a supported language like ITBSKernel.LANGUAGE_JPAQL
   * @param query_parameters a bunch of key/value parameters that are supported to the query engine to refine its execution.<br>
   *    It can be null or empty if no refinements are supplied.<br>
   *    //TODO documents about the possible keys to supply. 
   * @return a List of object containing the results of the given query
   * @throws NoSuchObjectException if any of the source trace UID is not found
   * @throws UnsupportedLanguageException if the language parameter does not match a supported query language
   * @throws PermissionException if the connected user does not have the right to access a source trace or the query
   * @throws IncompatibleTemporalDomainsException if a the source traces does not share the same temporal domain
   * @throws QueryRuntimeException if the query fails due to a syntax problem or internal error
   */
  public List<Object> query(String[] trace_uids, String query, String language,
      Map<String, Serializable> query_parameters) throws NoSuchObjectException, UnsupportedLanguageException,
      QueryRuntimeException, PermissionException, IncompatibleTemporalDomainsException;

}
